package com.kawins.supers.tree;

import com.kawins.supers.tree.annonation.TreeChild;
import com.kawins.supers.tree.annonation.TreeId;
import com.kawins.supers.tree.annonation.TreeParentId;
import com.kawins.supers.tree.exp.TreeInitializeException;
import com.kawins.util.bean.BeanUtil;
import com.kawins.util.colle.ListKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author rankai
 *         createTime 2017-09-2017/9/29 14:35
 */
public class Bean2TreeUtil<T> {

    private static final Logger log = LoggerFactory.getLogger(Bean2TreeUtil.class);

    private List<T> returnList = new ArrayList<>();

    private boolean order;

    private LinkedHashMap<String, Integer> orderMap;

    public Bean2TreeUtil() {
    }

    public Bean2TreeUtil(LinkedHashMap<String, Integer> orderMap) {
        this.order = true;
        this.orderMap = orderMap;
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param sourceList 数据源
     * @param parentId   父id
     * @return 层级结果
     */
    public List<T> getChildNodesByParentId(List<T> sourceList, Object parentId) {
        if (sourceList == null || sourceList.isEmpty() || parentId == null) {
            log.error("数据源为 Null 或 为空 或 id 为 Null");
            return returnList;
        }
        if (order && !sourceList.isEmpty()) {
            ListKit.ListSort.sortMap(sourceList, orderMap);
        }
        for (T node : sourceList) {
            //遍历所有的父节点下的所有子节点
            if (getParentId(node).equals(parentId.toString())) {
                recursion(sourceList, node);
                returnList.add(node);
            }
        }
        return returnList;
    }

    /**
     * 根据节点的ID获取所有子节点
     *
     * @param sourceList 数据源
     * @param id         Id
     * @return 层级结果
     */
    public List<T> getChildNodesById(List<T> sourceList, Object id) throws TreeInitializeException {
        if (sourceList == null || sourceList.isEmpty() || id == null) {
            throw new TreeInitializeException("数据源为 Null 或 为空 或 id 为 Null");
        }
        if (order && !sourceList.isEmpty()) {
            ListKit.ListSort.sortMap(sourceList, orderMap);
        }
        for (T node : sourceList) {
            //遍历所有的父节点下的所有子节点
            if (getId(node).equals(id.toString())) {
                recursion(sourceList, node);
                returnList.add(node);
            }
        }
        return returnList;
    }

    private void recursion(List<T> sourceList, T node) {
        List<T> childList = getChildList(sourceList, node);//得到子节点列表
        if (order && childList != null && !childList.isEmpty()) {
            ListKit.ListSort.sortMap(childList, orderMap);
        }
        if (hasChild(sourceList, node)) {//判断是否有子节点
            setChild(node, childList);
            if (childList != null) {
                for (T childNode : childList) {
                    recursion(sourceList, childNode);
                }
            }
        } else {
            setChild(node, childList);
        }
    }

    //得到子节点列表
    private List<T> getChildList(List<T> list, T node) {
        List<T> nodeList = new ArrayList<>();
        for (T childNode : list) {
            if (getParentId(childNode).equals(getId(node))) {
                nodeList.add(childNode);
            }
        }
        return nodeList;
    }

    // 判断是否有子节点
    private boolean hasChild(List<T> list, T node) {
        return getChildList(list, node).size() > 0;
    }

    private String getParentId(T node) {
        return BeanUtil.getFiledValueByAnnotation(node, TreeParentId.class);
    }

    private String getId(T node) {
        return BeanUtil.getFiledValueByAnnotation(node, TreeId.class);
    }

    private void setChild(T node, List<T> nodeList) {
        BeanUtil.setFiledValueByAnnotation(node, TreeChild.class, nodeList);
    }

}
